#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <chrono>

class Logger {
public:
    static Logger& instance() {
        static Logger logger;
        return logger;
    }

    void log(const std::string& level, const std::string& message) {
        std::ofstream logFile("log.txt", std::ios::app);
        if (!logFile.is_open()) return;

        auto now = std::chrono::system_clock::now();
        std::time_t time = std::chrono::system_clock::to_time_t(now);
        std::tm* timeInfo = std::localtime(&time);

        std::ostringstream oss;
        oss << std::put_time(timeInfo, "%Y-%m-%d %H:%M:%S");
        std::string timestamp = oss.str();

        logFile << "[" << timestamp << "] [" << level << "] " << message << std::endl;
    }

private:
    Logger() = default;
    ~Logger() = default;
};

class Transaction {
public:
    enum class Type { Deposit, Withdrawal };

    Transaction(Type type, double amount) 
        : type(type), amount(amount), timestamp(std::time(nullptr)) {}


    std::string toString() const {
        std::ostringstream oss;
        oss << std::put_time(std::localtime(&timestamp), "%Y-%m-%d %H:%M:%S");
        return std::string(type == Type::Deposit ? "Пополнение" : "Снятие") 
               + " - " + oss.str() 
               + " - Сумма: " + std::to_string(amount);
    }


private:
    Type type;
    double amount;
    std::time_t timestamp;
};

class Account {
public:
    Account() : balance(0.0) {}

    void deposit(double amount) {
        if (amount <= 0) {
            Logger::instance().log("ERROR", "Ошибка пополнения: Некорректная сумма");
            return;
        }
        balance += amount;
        Transaction transaction(Transaction::Type::Deposit, amount);
        transactions.push_back(transaction);
        Logger::instance().log("INFO", "Пополнение: " + std::to_string(amount) + 
                                     " | Баланс: " + std::to_string(balance));
    }

    void withdraw(double amount) {
        if (amount <= 0) {
            Logger::instance().log("ERROR", "Ошибка снятия: Некорректная сумма");
            return;
        }
        if (amount > balance) {
            Logger::instance().log("ERROR", "Ошибка снятия: Недостаточно средств");
            return;
        }
        balance -= amount;
        Transaction transaction(Transaction::Type::Withdrawal, amount);
        transactions.push_back(transaction);
        Logger::instance().log("INFO", "Снятие: " + std::to_string(amount) + 
                                     " | Баланс: " + std::to_string(balance));
    }

    void printTransactions() const {
        for (const auto& t : transactions) {
            std::cout << t.toString() << std::endl;
        }
    }

private:
    double balance;
    std::vector<Transaction> transactions;
};

int main() {
    Account account;
    account.deposit(100.0);
    account.withdraw(50.0);
    account.withdraw(100.0);
    account.printTransactions();
    return 0;
}
